package com.smartcruise.util.schedulerUtil;

import android.text.TextUtils;

import com.smartcruise.util.pushUtil.NotificationUtils;
import com.tencent.bugly.crashreport.CrashReport;

import org.quartz.Calendar;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.BaseCalendar;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.spi.OperableTrigger;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.TimeZone;

/**
 * Created by FengChaoQun
 * on 2018/2/24 0024
 */

public class CronTransfer {

    public static Date getNextData(String cron) {
        CronTriggerImpl cronTrigger = null;
        try {
            cronTrigger = new CronTriggerImpl("1", "1", cron);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        List<Date> dates = computeFireTimes(cronTrigger, new BaseCalendar(TimeZone.getDefault()), 1);
        if (dates != null && !dates.isEmpty()) {
            return dates.get(0);
        } else {
            return null;
        }
    }

    public static List<Date> computeFireTimes(CronTriggerImpl trigg, Calendar cal, int numTimes) {
        LinkedList<Date> lst = new LinkedList();
        OperableTrigger t = (OperableTrigger) trigg.clone();
        if (t.getNextFireTime() == null) {
            t.computeFirstFireTime(cal);
        }

        for (int i = 0; i < numTimes; ++i) {
            Date d = t.getNextFireTime();
            if (d == null) {
                break;
            }

            lst.add(d);
            t.triggered(cal);
        }

        return Collections.unmodifiableList(lst);
    }

    public static List<Date> computeFireTimesBetween(String cron, Date from, Date to) {
        if (TextUtils.isEmpty(cron)) {
            return null;
        }
        CronTriggerImpl cronTrigger = null;
        try {
            cronTrigger = new CronTriggerImpl("1", "1", cron);
            return computeFireTimesBetween(cronTrigger, new BaseCalendar(TimeZone.getDefault()), from, to);
        } catch (ParseException e) {
            e.printStackTrace();
            CrashReport.postCatchedException(e);
            NotificationUtils.bugNotification("解析cron表达式出现异常:" + e.getMessage());
            return null;
        }
    }

    public static List<Date> computeFireTimesBetween(OperableTrigger trigg,
                                                     org.quartz.Calendar cal, Date from, Date to) {
        LinkedList<Date> lst = new LinkedList<Date>();

        OperableTrigger t = (OperableTrigger) trigg.clone();

        if (t.getNextFireTime() == null) {
            t.setStartTime(from);
            t.setEndTime(to);
            t.computeFirstFireTime(cal);
        }

        while (true) {
            Date d = t.getNextFireTime();
            if (d != null) {
                if (d.before(from)) {
                    t.triggered(cal);
                    continue;
                }
                if (d.after(to)) {
                    break;
                }
                lst.add(d);
                t.triggered(cal);
            } else {
                break;
            }
        }

        return java.util.Collections.unmodifiableList(lst);
    }

    public static void go() throws Exception {
        // 首先，必需要取得一个Scheduler的引用
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();
        String time = "0 51 11 ? * *";
        // jobs可以在scheduled的sched.start()方法前被调用

        // job 1将每隔20秒执行一次
        JobDetail job = new JobDetailImpl("job1", "group1", myJob.class);
        CronTrigger trigger = new CronTriggerImpl("trigger1", "group1", time);
        Date ft = sched.scheduleJob(job, trigger);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println(
                job.getKey() + " 已被安排执行于: " + sdf.format(ft) + "，并且以如下重复规则重复执行: " + trigger.getCronExpression());

        // 开始执行，start()方法被调用后，计时器就开始工作，计时调度中允许放入N个Job
        sched.start();
        try {
            // 主线程等待一分钟
            Thread.sleep(60L * 1000L);
        } catch (Exception e) {
        }
        // 关闭定时调度，定时器不再工作
        sched.shutdown(true);
    }

    class myJob implements Job {
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            System.out.println(sdf.format(new Date()));
        }

    }

}
